﻿using SQLDeploy.Data.Deployment.Steps.Tasks;
using SQLDeploy.Data.Internal;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;


namespace SQLDeploy.Data.Deployment.Steps
{
    public class Step : ValidationNotifier, IComparable
    {
        private int _id = -1;
        private string _name;
        private ObservableCollection<_BaseTask> _tasks = new ObservableCollection<_BaseTask>();
        private bool? _tasksInParellel = null;
        private Deployment _deploy;

        public Step(Deployment deployment)
        {
            if (deployment == null)
                throw new ArgumentNullException("deployment cannot be null");
            _deploy = deployment;
        }

        public int Id
        {
            get { return _id; }
            set
            {
                if (value < 1)
                    throw new ArgumentException("Id must be a positive Integer.");
                if (value != _id)
                {
                    _id = value;
                    OnPropertyChanged("Id");
                }
            }
        }

        public string Name
        {
            get { return _name; }
            set
            {
                if (string.IsNullOrEmpty(value))
                    throw new ArgumentNullException("Name cannot be Null or Empty");
                if (_name == null ||
                    !Internal.Shared.DefaultStringComparer().Equals(_name, value))
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        public bool? ParellelExecution
        {
            get
            {
                return _tasksInParellel;
            }
            set
            {
                if (_tasksInParellel == null ||
                    value == null ||
                    _tasksInParellel != value)
                {
                    _tasksInParellel = value;
                    OnPropertyChanged("ParellelExecution");
                }
            }
        }

        public bool Parellel
        {
            get
            {
                if (ParellelExecution == null)
                    return this._deploy.ParellelExecution;
                else
                    return (bool)ParellelExecution;
            }
        }

        public ObservableCollection<_BaseTask> Tasks
        {
            get { return _tasks; }
            set
            {
                _tasks = value;
                OnPropertyChanged("Tasks");
            }
        }

        public int CompareTo(object obj)
        {
            if (obj == null)
                throw new ArgumentNullException("obj is null");
            if (!(obj is Step))
                throw new ArgumentException("obj must be instance of Step");
            Step other = (Step)obj;
            if (other._id == this._id)
                throw new ArgumentException("Duplicate Id!");
            return Internal.Shared.DefaultStringComparer().Compare(this._name, other._name);
        }

        public override bool performValidation()
        {
            bool allTasksValid = true;
            foreach (_BaseTask task in Tasks)
            {
                if (!task.performValidation())
                {
                    allTasksValid = false;
                }
            }
            return allTasksValid;
        }
    }
}
